package vn.bang.communication;

import vn.bang.utility.StringUtil;

public class Command {

	static public final Integer MAX_PARAMETERS_LENGTH = 15;
	
	public enum CommandName {// TODO
		NEW_GAME("NEW_GAME"), MOVE("MOVE"), LOGIN("LOGIN");

		private final String value;

		private CommandName(String s) {
			value = s;
		}

		@Override
		public String toString() {
			return value;
		}
	}

	private String name;
	private String[] parameters;
	private boolean valid;

	public Command(String statement) {
		StringBuilder name = new StringBuilder();
		String[] parameters = new String[MAX_PARAMETERS_LENGTH];
		parseStatement(statement, name, parameters);
		initialMembers(name.toString(), parameters);
	}

	public Command(byte[] data) {
		StringBuilder name = new StringBuilder();
		String[] parameters = new String[MAX_PARAMETERS_LENGTH];
		parseData(data, name, parameters);
		initialMembers(name.toString(), parameters);
	}
	
	public Command(String name, String[] parameters) {
		initialMembers(name, parameters);
	}

	public boolean isName(CommandName commandName) {
		return name.equals(commandName.toString());
	}
	
	private void parseData(byte[] data, StringBuilder outName, String[] outParameters) {
		String statement = new String(data);
		parseStatement(statement, outName, outParameters);
	}
	
	private void parseStatement(String statement, StringBuilder outName,
			String[] outParameters) {
		if (null == statement || null == outName || null == outParameters) {
			throw new IllegalArgumentException("Parameters must be not null.");
		}
		
		// Initial output variables.
		outName.delete(0, outName.length());
		for (int i = 0; i < outParameters.length; i++) {
			outParameters[i] = null;
		}
		
		// Set output variables.
		String[] parts = statement.split(" ");
		outName.append(parts[0]);
		for (int i = 1; i < parts.length; i++) {
			outParameters[i - 1] = parts[i].trim();
		}
		
	}

	private void initialMembers(String name, String[] parameters) {
		this.valid = validate(name, parameters);
		if (valid) {
			this.name = name;
			this.parameters = parameters;
		}
	}

	private boolean validate(String name, String[] parameters) {
		if (!hasCommandName(name)) {
			return false;
		}
		if (!hasParameters(name, parameters)) {
			return false;
		}
		return true;
	}

	private boolean hasParameters(String name, String[] parameters) {
		if (null == parameters || parameters.length == 0) {
			return false;
		}
		// TODO
		return true;
	}

	private boolean hasCommandName(String name) {
		if (StringUtil.isNullOrEmpty(name)) {
			return false;
		}

		if (null == CommandName.valueOf(name)) {
			return false;
		}

		return true;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String[] getParameters() {
		return parameters;
	}

	public void setParameters(String[] parameters) {
		this.parameters = parameters;
	}

	@Override
    public String toString() {
		if (!valid)
			return "";
		
		final StringBuilder builder = new StringBuilder();
		builder.append(name);
		for (int i = 0; i < parameters.length; i++) {
			if (null != parameters[i]) {
				builder.append(" " + parameters[i]);
			}
		}
		return builder.toString();
    }
}
